package rabbitmq

import (
	"fmt"
	"portal_mq/global"

	amqp "github.com/rabbitmq/amqp091-go"
	"go.uber.org/zap"
)

func NewRabbitMQTopicConsumer(opts *RabbitOptions) *RabbitMQ {
	mq := &RabbitMQ{
		QueueName:    opts.QueueName,
		ExchangeName: opts.ExchangeName,
		BindingKey:   opts.BindingKey,
	}

	// dial
	var err error
	rabbitURL := fmt.Sprintf("amqp://%s:%s@%s:%d/", global.ServiceConfig.RabbitMQ.Username, global.ServiceConfig.RabbitMQ.Password, global.ServiceConfig.RabbitMQ.Host, global.ServiceConfig.RabbitMQ.Port)
	mq.conn, err = amqp.Dial(rabbitURL)
	if err != nil {
		zap.L().Error("Failed to connect to RabbitMQ", zap.Error(err))
		return nil
	}

	// get channel
	mq.channel, err = mq.conn.Channel()
	if err != nil {
		zap.L().Error("Failed to create channel", zap.Error(err))
		return nil
	}

	// exchange declare
	err = mq.channel.ExchangeDeclare(
		mq.ExchangeName,
		"topic",
		true,  // durable
		false, // auto delete
		false, // internal
		false, // no wait
		nil,   // arguments
	)
	if err != nil {
		zap.L().Error("Failed to declare exchange", zap.Error(err))
		return nil
	}

	// queue declare
	_, err = mq.channel.QueueDeclare(
		opts.QueueName,
		false, // durable
		false, // auto delete
		false, // exclusive if false, only one consumer can consume from this queue, if true, multiple consumers can consume from this queue.
		false, // no wait
		nil,   // arguments
	)

	if err != nil {
		zap.L().Error("Failed to declare queue", zap.Error(err))
		return nil
	}

	// bind queue
	err = mq.channel.QueueBind(
		mq.QueueName,
		mq.BindingKey,
		mq.ExchangeName,
		false,
		nil,
	)

	if err != nil {
		zap.L().Error("Failed to bind queue", zap.Error(err))
		return nil
	}

	return mq
}

func (r *RabbitMQ) Consume() <-chan amqp.Delivery {

	// consume
	msgs, err := r.channel.Consume(
		r.QueueName,
		"",    // consumer tag
		true,  // auto ack
		false, // exclusive
		false, // no local
		false, // no wait
		nil,   // args
	)
	if err != nil {
		zap.L().Error("Failed to consume", zap.Error(err))
		return nil
	}

	return msgs
}
